package org.csu.onlineedubackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.csu.onlineedubackend.entity.Lesson;
import org.csu.onlineedubackend.entity.LessonProgress;
import org.csu.onlineedubackend.entity.StudentCourseDanmaku;
import org.csu.onlineedubackend.entity.User;
import org.csu.onlineedubackend.entity.VideoStudentCourseProgress;
import org.csu.onlineedubackend.mapper.LessonMapper;
import org.csu.onlineedubackend.mapper.LessonProgressMapper;
import org.csu.onlineedubackend.mapper.StudentCourseDanmakuMapper;
import org.csu.onlineedubackend.mapper.UserMapper;
import org.csu.onlineedubackend.mapper.VideoStudentCourseProgressMapper;
import org.csu.onlineedubackend.service.StudentCourseVideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
public class StudentCourseVideoServiceImpl implements StudentCourseVideoService {

    @Autowired
    private VideoStudentCourseProgressMapper videoProgressMapper;
    
    @Autowired
    private LessonProgressMapper lessonProgressMapper;
    
    @Autowired
    private StudentCourseDanmakuMapper danmakuMapper;
    
    @Autowired
    private LessonMapper lessonMapper;
    
    @Autowired
    private UserMapper userMapper;

    @Override
    public VideoStudentCourseProgress getVideoProgress(Integer studentId, Integer lessonId) {
        log.info("获取视频播放进度 - 学生ID: {}, 课时ID: {}", studentId, lessonId);
        return videoProgressMapper.selectByStudentAndLesson(studentId, lessonId);
    }

    @Override
    @Transactional
    public boolean updateVideoProgress(VideoStudentCourseProgress progress) {
        try {
            log.info("更新视频播放进度 - 学生ID: {}, 课时ID: {}, 当前时间: {}", 
                    progress.getStudentId(), progress.getLessonId(), progress.getCurrentTime());
            
            // 首先验证课时是否存在
            Lesson lesson = lessonMapper.selectById(progress.getLessonId());
            if (lesson == null) {
                log.error("更新视频播放进度失败 - 课时ID不存在: {}", progress.getLessonId());
                return false;
            }
            
            // 验证学生是否存在
            User student = userMapper.selectById(progress.getStudentId());
            if (student == null) {
                log.error("更新视频播放进度失败 - 学生ID不存在: {}", progress.getStudentId());
                return false;
            }
            
            // 设置最后观看时间
            LocalDateTime now = LocalDateTime.now();
            progress.setLastWatched(now);
            
            boolean result = false;
            
            // 1. 更新video_student_course_progress表
            VideoStudentCourseProgress existingProgress = 
                    videoProgressMapper.selectByStudentAndLesson(progress.getStudentId(), progress.getLessonId());
            
            if (existingProgress == null) {
                // 创建新记录
                log.debug("创建新的video_student_course_progress记录");
                result = videoProgressMapper.insert(progress) > 0;
                log.info("插入video_student_course_progress记录结果: {}", result ? "成功" : "失败");
            } else {
                // 更新现有记录，使用UpdateWrapper而不是updateById
                log.debug("更新现有video_student_course_progress记录 ID: {}", existingProgress.getId());
                UpdateWrapper<VideoStudentCourseProgress> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("id", existingProgress.getId())
                        .set("`current_time`", progress.getCurrentTime())
                        .set("is_completed", progress.getIsCompleted())
                        .set("last_watched", progress.getLastWatched())
                        .set("playback_rate", progress.getPlaybackRate())
                        .set("quality_setting", progress.getQualitySetting())
                        .set("subtitle_enabled", progress.getSubtitleEnabled())
                        .set("volume", progress.getVolume())
                        .set("danmaku_enabled", progress.getDanmakuEnabled())
                        .set("pip_enabled", progress.getPipEnabled());
                
                result = videoProgressMapper.update(null, updateWrapper) > 0;
                log.info("更新video_student_course_progress记录结果: {}", result ? "成功" : "失败");
            }
            
            // 2. 同时更新lesson_progress表
            try {
                // 先检查是否已存在记录
                log.debug("查询lesson_progress记录 - 学生ID: {}, 课时ID: {}", progress.getStudentId(), progress.getLessonId());
                LessonProgress lessonProgress = 
                        lessonProgressMapper.selectByStudentAndLesson(progress.getStudentId(), progress.getLessonId());
                
                // 获取课时信息，以便计算进度百分比
                float progressPercent = 0.0f;
                
                // 如果能获取到课时信息并且有时长，则计算百分比
                if (lesson != null && lesson.getDuration() != null && lesson.getDuration() > 0) {
                    progressPercent = (float) progress.getCurrentTime() * 100 / lesson.getDuration();
                    // 确保百分比不超过100
                    progressPercent = Math.min(progressPercent, 100.0f);
                    log.debug("计算进度百分比: {}%, 当前时间: {}, 总时长: {}", 
                            progressPercent, progress.getCurrentTime(), lesson.getDuration());
                } else {
                    // 如果无法获取课时信息，则直接使用当前时间作为进度值
                    progressPercent = (float) progress.getCurrentTime();
                    log.debug("无法获取课时时长，使用当前时间作为进度: {}", progressPercent);
                }
                
                if (lessonProgress == null) {
                    // 创建新记录
                    log.info("lesson_progress表中不存在记录，创建新记录");
                    lessonProgress = new LessonProgress();
                    lessonProgress.setStudentId(progress.getStudentId());
                    lessonProgress.setLessonId(progress.getLessonId());
                    lessonProgress.setProgress(progressPercent);
                    lessonProgress.setLastWatch(now);
                    
                    log.info("准备插入新的lesson_progress记录 - 学生ID: {}, 课时ID: {}, 进度: {}", 
                            progress.getStudentId(), progress.getLessonId(), progressPercent);
                    
                    // 打印完整的实体对象信息，用于调试
                    log.debug("LessonProgress对象详情: {}", lessonProgress);
                    
                    try {
                        // 直接使用SQL语句插入，避免可能的实体映射问题
                        String sql = "INSERT INTO lesson_progress (student_id, lesson_id, progress, last_watch) VALUES (?, ?, ?, ?)";
                        int insertResult = lessonProgressMapper.insert(lessonProgress);
                        log.info("插入lesson_progress记录结果: {} - ID: {}, 学生ID: {}, 课时ID: {}", 
                                insertResult > 0 ? "成功" : "失败", 
                                lessonProgress.getId(), 
                                progress.getStudentId(), 
                                progress.getLessonId());
                    } catch (Exception e) {
                        log.error("插入lesson_progress记录异常 - 学生ID: {}, 课时ID: {}, 错误: {}", 
                                progress.getStudentId(), progress.getLessonId(), e.getMessage(), e);
                        throw e; // 重新抛出异常以触发事务回滚
                    }
                } else {
                    // 更新现有记录
                    log.info("lesson_progress表中已存在记录，更新记录 - ID: {}", lessonProgress.getId());
                    
                    // 使用UpdateWrapper更新
                    UpdateWrapper<LessonProgress> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("id", lessonProgress.getId())
                            .set("progress", progressPercent)
                            .set("last_watch", now);
                    
                    log.info("准备更新lesson_progress记录 - ID: {}, 学生ID: {}, 课时ID: {}, 进度: {}", 
                            lessonProgress.getId(), progress.getStudentId(), progress.getLessonId(), progressPercent);
                    
                    try {
                        int updateResult = lessonProgressMapper.update(null, updateWrapper);
                        log.info("更新lesson_progress记录结果: {} - ID: {}, 学生ID: {}, 课时ID: {}", 
                                updateResult > 0 ? "成功" : "失败", lessonProgress.getId(), 
                                progress.getStudentId(), progress.getLessonId());
                    } catch (Exception e) {
                        log.error("更新lesson_progress记录异常 - ID: {}, 学生ID: {}, 课时ID: {}, 错误: {}", 
                                lessonProgress.getId(), progress.getStudentId(), progress.getLessonId(), 
                                e.getMessage(), e);
                        throw e; // 重新抛出异常以触发事务回滚
                    }
                }
            } catch (Exception e) {
                log.error("处理lesson_progress记录时发生异常", e);
                throw e; // 重新抛出异常以触发事务回滚
            }
            
            return result;
        } catch (Exception e) {
            log.error("更新视频播放进度发生异常", e);
            throw e; // 重新抛出异常以触发事务回滚
        }
    }

    @Override
    @Transactional
    public boolean markVideoCompleted(Integer studentId, Integer lessonId) {
        try {
            log.info("标记视频为已完成 - 学生ID: {}, 课时ID: {}", studentId, lessonId);
            
            // 首先验证课时是否存在
            Lesson lesson = lessonMapper.selectById(lessonId);
            if (lesson == null) {
                log.error("标记视频为已完成失败 - 课时ID不存在: {}", lessonId);
                return false;
            }
            
            // 验证学生是否存在
            User student = userMapper.selectById(studentId);
            if (student == null) {
                log.error("标记视频为已完成失败 - 学生ID不存在: {}", studentId);
                return false;
            }
            
            LocalDateTime now = LocalDateTime.now();
            boolean result = false;
            
            // 1. 更新video_student_course_progress表
            VideoStudentCourseProgress existingProgress = 
                    videoProgressMapper.selectByStudentAndLesson(studentId, lessonId);
            
            if (existingProgress == null) {
                // 创建新记录并标记为已完成
                VideoStudentCourseProgress progress = new VideoStudentCourseProgress();
                progress.setStudentId(studentId);
                progress.setLessonId(lessonId);
                progress.setIsCompleted(true);
                progress.setLastWatched(now);
                result = videoProgressMapper.insert(progress) > 0;
            } else {
                // 更新现有记录为已完成
                UpdateWrapper<VideoStudentCourseProgress> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("student_id", studentId)
                        .eq("lesson_id", lessonId)
                        .set("is_completed", true)
                        .set("last_watched", now);
                
                result = videoProgressMapper.update(null, updateWrapper) > 0;
            }
            
            // 2. 同时更新lesson_progress表
            try {
                LessonProgress lessonProgress = 
                        lessonProgressMapper.selectByStudentAndLesson(studentId, lessonId);
                
                if (lessonProgress == null) {
                    // 创建新记录
                    lessonProgress = new LessonProgress();
                    lessonProgress.setStudentId(studentId);
                    lessonProgress.setLessonId(lessonId);
                    lessonProgress.setProgress(100.0f); // 已完成，进度设为100%
                    lessonProgress.setLastWatch(now);
                    
                    log.info("标记完成：准备插入新的lesson_progress记录 - 学生ID: {}, 课时ID: {}", studentId, lessonId);
                    try {
                        // 直接使用SQL语句插入，避免可能的实体映射问题
                        String sql = "INSERT INTO lesson_progress (student_id, lesson_id, progress, last_watch) VALUES (?, ?, ?, ?)";
                        int insertResult = lessonProgressMapper.insert(lessonProgress);
                        log.info("标记完成：插入lesson_progress记录结果: {} - ID: {}, 学生ID: {}, 课时ID: {}", 
                                insertResult > 0 ? "成功" : "失败", 
                                lessonProgress.getId(), 
                                studentId, 
                                lessonId);
                    } catch (Exception e) {
                        log.error("标记完成：插入lesson_progress记录异常 - 学生ID: {}, 课时ID: {}, 错误: {}", 
                                studentId, lessonId, e.getMessage(), e);
                        throw e; // 重新抛出异常以触发事务回滚
                    }
                } else {
                    // 更新现有记录为已完成
                    UpdateWrapper<LessonProgress> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("id", lessonProgress.getId())
                            .set("progress", 100.0f) // 已完成，进度设为100%
                            .set("last_watch", now);
                    
                    log.info("标记完成：准备更新lesson_progress记录 - ID: {}, 学生ID: {}, 课时ID: {}", 
                            lessonProgress.getId(), studentId, lessonId);
                    try {
                        int updateResult = lessonProgressMapper.update(null, updateWrapper);
                        log.info("标记完成：更新lesson_progress记录结果: {} - ID: {}, 学生ID: {}, 课时ID: {}", 
                                updateResult > 0 ? "成功" : "失败", lessonProgress.getId(), studentId, lessonId);
                    } catch (Exception e) {
                        log.error("标记完成：更新lesson_progress记录异常 - ID: {}, 学生ID: {}, 课时ID: {}, 错误: {}", 
                                lessonProgress.getId(), studentId, lessonId, e.getMessage(), e);
                        throw e; // 重新抛出异常以触发事务回滚
                    }
                }
            } catch (Exception e) {
                log.error("标记完成：处理lesson_progress记录时发生异常", e);
                throw e; // 重新抛出异常以触发事务回滚
            }
            
            return result;
        } catch (Exception e) {
            log.error("标记视频为已完成发生异常", e);
            throw e; // 重新抛出异常以触发事务回滚
        }
    }

    @Override
    public boolean updateVideoSettings(Integer studentId, Integer lessonId, Float playbackRate,
                                      String qualitySetting, Boolean subtitleEnabled) {
        log.info("更新视频播放设置 - 学生ID: {}, 课时ID: {}, 播放速度: {}, 清晰度: {}, 字幕: {}", 
                studentId, lessonId, playbackRate, qualitySetting, subtitleEnabled);
        
        try {
            VideoStudentCourseProgress existingProgress = 
                    videoProgressMapper.selectByStudentAndLesson(studentId, lessonId);
            
            if (existingProgress == null) {
                // 创建新记录
                VideoStudentCourseProgress progress = new VideoStudentCourseProgress();
                progress.setStudentId(studentId);
                progress.setLessonId(lessonId);
                progress.setPlaybackRate(playbackRate);
                progress.setQualitySetting(qualitySetting);
                progress.setSubtitleEnabled(subtitleEnabled);
                progress.setLastWatched(LocalDateTime.now());
                return videoProgressMapper.insert(progress) > 0;
            } else {
                // 更新现有记录
                UpdateWrapper<VideoStudentCourseProgress> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("student_id", studentId)
                        .eq("lesson_id", lessonId)
                        .set("playback_rate", playbackRate)
                        .set("quality_setting", qualitySetting)
                        .set("subtitle_enabled", subtitleEnabled)
                        .set("last_watched", LocalDateTime.now());
                
                return videoProgressMapper.update(null, updateWrapper) > 0;
            }
        } catch (Exception e) {
            log.error("更新视频播放设置失败", e);
            return false;
        }
    }
    
    @Override
    public boolean updateAdvancedSettings(Integer studentId, Integer lessonId, Float volume,
                                        Boolean danmakuEnabled, Boolean pipEnabled) {
        log.info("更新视频高级设置 - 学生ID: {}, 课时ID: {}, 音量: {}, 弹幕: {}, 画中画: {}", 
                studentId, lessonId, volume, danmakuEnabled, pipEnabled);
        
        try {
            VideoStudentCourseProgress existingProgress = 
                    videoProgressMapper.selectByStudentAndLesson(studentId, lessonId);
            
            if (existingProgress == null) {
                // 创建新记录
                VideoStudentCourseProgress progress = new VideoStudentCourseProgress();
                progress.setStudentId(studentId);
                progress.setLessonId(lessonId);
                progress.setVolume(volume);
                progress.setDanmakuEnabled(danmakuEnabled);
                progress.setPipEnabled(pipEnabled);
                progress.setLastWatched(LocalDateTime.now());
                return videoProgressMapper.insert(progress) > 0;
            } else {
                // 更新现有记录
                UpdateWrapper<VideoStudentCourseProgress> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("student_id", studentId)
                        .eq("lesson_id", lessonId)
                        .set("volume", volume)
                        .set("danmaku_enabled", danmakuEnabled)
                        .set("pip_enabled", pipEnabled)
                        .set("last_watched", LocalDateTime.now());
                
                return videoProgressMapper.update(null, updateWrapper) > 0;
            }
        } catch (Exception e) {
            log.error("更新视频高级设置失败", e);
            return false;
        }
    }
    
    @Override
    public List<StudentCourseDanmaku> getDanmakusByLessonId(Integer lessonId) {
        log.info("获取课时弹幕列表 - 课时ID: {}", lessonId);
        return danmakuMapper.selectByLessonId(lessonId);
    }
    
    @Override
    public List<StudentCourseDanmaku> getDanmakusByTimeRange(Integer lessonId, Integer startTime, Integer endTime) {
        log.info("获取指定时间范围内的弹幕列表 - 课时ID: {}, 开始时间: {}, 结束时间: {}", lessonId, startTime, endTime);
        return danmakuMapper.selectByLessonIdAndTimeRange(lessonId, startTime, endTime);
    }
    
    @Override
    public boolean sendDanmaku(StudentCourseDanmaku danmaku) {
        log.info("发送弹幕 - 学生ID: {}, 课时ID: {}, 内容: {}, 时间点: {}", 
                danmaku.getStudentId(), danmaku.getLessonId(), danmaku.getContent(), danmaku.getTimePoint());
        
        try {
            // 设置创建时间和状态
            danmaku.setCreatedAt(LocalDateTime.now());
            danmaku.setStatus("normal");
            
            // 如果没有设置字体大小，设置默认值
            if (danmaku.getFontSize() == null) {
                danmaku.setFontSize(16);
            }
            
            // 如果没有设置颜色，设置默认值
            if (danmaku.getColor() == null || danmaku.getColor().isEmpty()) {
                danmaku.setColor("#FFFFFF");
            }
            
            return danmakuMapper.insert(danmaku) > 0;
        } catch (Exception e) {
            log.error("发送弹幕失败", e);
            return false;
        }
    }
}